package com.tdengine.tdengine;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Configuration
@ConditionalOnProperty(value = "spring.tdengine-server.enabled",havingValue = "true")
@Data
@MapperScan(basePackages = {"com.tdengine.mapper"})
public class TDengineConfig {


    @Value("${spring.tdengine-server.url}")
    private String jdbc;

    /**
     * 加载/resource/mapper/tdengine目录下的所有mapper.xml
     * mybatis能够对TDengine的mappeer.xml进行解析，那么就能对应的mapper接口创建代理对象
     * mybatis只是SQL语句的管理工具，并不关注你的数据源是mysql还是TDengine
     */
    private static final String [] TD_MAPPERXML_PATHS={"classpath:mapper/tdengine/*Mapper.xml"};

    /**
     * 创建数据源对象
     */
    @Bean(name = "tDengineDataSource")
    @ConfigurationProperties(prefix = "spring.tdengine-server")
    public DataSource tdengineDataSource() {
        return new DruidDataSource();
    }

    /**
     * 创建SqlSessionFactory
     */
    @Bean(name = "tDengineSqlSessionFactory")
    public SqlSessionFactory tDengineSqlSessionFactory(@Qualifier("tDengineDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations(TD_MAPPERXML_PATHS));
        sqlSessionFactoryBean.setDataSource(dataSource);

        /**
         * 动态给当前sqlSessionFactoryBean添加拦截器对象
         */
        //创建拦截器对象，这是使用Mybatis-plus的拦截器
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //创建Mybatis-plus的分页处理器
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        //把分页处理器加入到SQL拦截器中去
        interceptor.addInnerInterceptor(paginationInnerInterceptor);

        //把拦截器设置到sqlSessionFactoryBean对象中，那么mybatis在创建MapperProxy对象的时候，这个MybatisPlusInterceptor就会代理当前Mapper.java对象
        sqlSessionFactoryBean.setPlugins(interceptor);
        return sqlSessionFactoryBean.getObject();
    }

    /**
     * 事务管理器
     */
    @Bean(name = "tDengineTransactionManager")
    public DataSourceTransactionManager tdengineTransactionManager() throws Exception {
        return new DataSourceTransactionManager(tdengineDataSource());
    }

    @Bean(name = "tdengineSqlSessionTemplate")
    public SqlSessionTemplate tdengineSqlSessionTemplate(@Qualifier("tDengineSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * @param mapperLocations
     * @return
     */
    private Resource[] resolveMapperLocations(String[] mapperLocations) {
        PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList<Resource>();
        if (mapperLocations != null){
            for (String mapperLocation : mapperLocations){
                try{
                    Resource[] mappers = patternResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                }
                catch (IOException e){
                    log.error("加载TDengine的mapper.xml失败：{}",e.getMessage());
                }
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }
}

